The setf macro is the most basic
way to operate on generalized variables.
This macro evaluates form and stores it in place, which must be a valid generalized variable form. If there are several place and form pairs, the assignments are done sequentially just as with
setq.setfreturns the value of the last form.The following Lisp forms will work as generalized variables, and so may appear in the place argument of
setf:
- A symbol naming a variable. In other words,
(setf x y)is exactly equivalent to(setq x y), andsetqitself is strictly speaking redundant now thatsetfexists. Many programmers continue to prefersetqfor setting simple variables, though, purely for stylistic or historical reasons. The macro(setf x y)actually expands to(setq x y), so there is no performance penalty for using it in compiled code.- A call to any of the following Lisp functions:
car cdr caar .. cddddr nth rest first .. tenth aref elt nthcdr symbol-function symbol-value symbol-plist get get* getf gethash subseqNote that for
nthcdrandgetf, the list argument of the function must itself be a valid place form. For example,(setf (nthcdr 0 foo) 7)will setfooitself to 7. Note thatpushandpopon annthcdrplace can be used to insert or delete at any position in a list. The use ofnthcdras a place form is an extension to standard Common Lisp.- The following Emacs-specific functions are also
setf-able.buffer-file-name marker-position buffer-modified-p match-data buffer-name mouse-position buffer-string overlay-end buffer-substring overlay-get current-buffer overlay-start current-case-table point current-column point-marker current-global-map point-max current-input-mode point-min current-local-map process-buffer current-window-configuration process-filter default-file-modes process-sentinel default-value read-mouse-position documentation-property screen-height extent-data screen-menubar extent-end-position screen-width extent-start-position selected-window face-background selected-screen face-background-pixmap selected-frame face-font standard-case-table face-foreground syntax-table face-underline-p window-buffer file-modes window-dedicated-p frame-height window-display-table frame-parameters window-height frame-visible-p window-hscroll frame-width window-point get-register window-start getenv window-width global-key-binding x-get-secondary-selection keymap-parent x-get-selection local-key-binding mark mark-markerMost of these have directly corresponding “set” functions, like
use-local-mapforcurrent-local-map, orgoto-charforpoint. A few, likepoint-min, expand to longer sequences of code when they aresetf'd ((narrow-to-region x (point-max))in this case).- A call of the form
(substringsubplace n[m]), where subplace is itself a valid generalized variable whose current value is a string, and where the value stored is also a string. The new string is spliced into the specified part of the destination string. For example:(setq a (list "hello" "world")) ⇒ ("hello" "world") (cadr a) ⇒ "world" (substring (cadr a) 2 4) ⇒ "rl" (setf (substring (cadr a) 2 4) "o") ⇒ "o" (cadr a) ⇒ "wood" a ⇒ ("hello" "wood")The generalized variable
buffer-substring, listed above, also works in this way by replacing a portion of the current buffer.- A call of the form
(apply 'func...)or(apply (functionfunc) ...), where func is asetf-able function whose store function is “suitable” in the sense described in Steele's book; since none of the standard Emacs place functions are suitable in this sense, this feature is only interesting when used with places you define yourself withdefine-setf-methodor the long form ofdefsetf.- A macro call, in which case the macro is expanded and
setfis applied to the resulting form.- Any form for which a
defsetfordefine-setf-methodhas been made.Using any forms other than these in the place argument to
setfwill signal an error.The
setfmacro takes care to evaluate all subforms in the proper left-to-right order; for example,(setf (aref vec (incf i)) i)looks like it will evaluate
(incf i)exactly once, before the following access toi; thesetfexpander will insert temporary variables as necessary to ensure that it does in fact work this way no matter what setf-method is defined foraref. (In this case,asetwould be used and no such steps would be necessary sinceasettakes its arguments in a convenient order.)However, if the place form is a macro which explicitly evaluates its arguments in an unusual order, this unusual order will be preserved. Adapting an example from Steele, given
(defmacro wrong-order (x y) (list 'aref y x))the form
(setf (wrong-ordera b) 17)will evaluate b first, then a, just as in an actual call towrong-order.